package cn.tedu.design;
/**本类用于实现单例设计模式方案2--懒汉式*/
public class Singleton2 {
    public static void main(String[] args) {
        MySingle2 single1 = MySingle2.getMySingle2();
        MySingle2 single2 = MySingle2.getMySingle2();
        MySingle2 single3 = MySingle2.getMySingle2();
        System.out.println(single1==single2);
        System.out.println(single3);
    }
}
class MySingle2{
    static Object o = new Object();
    private  MySingle2(){}
//    private static MySingle2 mySingle2 = new MySingle2();
    //定义一个本类对象类型的成员变量，暂时先不创建对象
    //这是一个引用类型的成员变量，默认值为null，用于存放一会创建出来的对象的地址值
private static MySingle2 single2;
    public static MySingle2 getMySingle2(){
        //如果single2变量保存的还是默认值null，说明还未创建对象
        /**有共享数据+多条语句操作数据，所以尽量提前处理，避免多线程数据安全隐患
         解决方案1：加同步代码块
         解决方案2：将本方法getSingle2()设置为同步方法*/
        synchronized (o){
            if (single2 == null){
                single2 = new MySingle2();//创建对象，将地址值交给single2保存
            }
            //如果single2变量的值不是null，说明之前已经创建过了，不用创建之间返回single2
            return single2;
        }

    }
}
/**关于单例设计模式的两种实现方式：
 * 1.饿汉式：不管你用不用这个类的对象，都会直接先创建一个
 * 2.懒汉式：先不给创建这个类的对象，等你需要的时候再创建--延迟加载的思想
 * 延迟加载的思想：是指不会在第一时间就把对象创建好占用内存
 * 而是什么时候用到，什么时候再去创建对象
 * 3.线程安全问题：由于我们存在唯一的对象single2,并且多条语句都操作了这个变量
 * 如果将程序放到多线程的环境下，就容易出现数据安全的问题，所以解决方案：
 * 1) 将3条语句都使用同步代码块包裹，保证同步排队的效果
 * 2) 由于getSingle2()只有这3条语句，所以也可以将本方法设置为同步方法*/


